---
title: Interfaces
description: Guide for defining Interface types in Pothos
---

## Defining Interface Types

Defining interfaces works exactly like [defining Objects](./objects), using `Interfaces` key in
SchemaTypes object for the builder, and `interfaceRef` rather than `objectRef`.

In this example we'll use an Animal class and a Giraffe class that extends it:

```typescript
export class Animal {
  diet: Diet;

  constructor(diet: Diet) {
    this.diet = diet;
  }
}

export class Giraffe extends Animal {
  name: string;
  birthday: Date;
  heightInMeters: number;

  constructor(name: string, birthday: Date, heightInMeters: number) {
    super(Diet.HERBIVOROUS);

    this.name = name;
    this.birthday = birthday;
    this.heightInMeters = heightInMeters;
  }
}
export enum Diet {
  HERBIVOROUS,
  CARNIVOROUS,
  OMNIVORIOUS,
}
```

Again, using classes is completely optional. The only requirement for interfaces is that the the
type used for defining objects must be a superset of the the types of any interfaces they implement.

Now that we have our classes set up we can define the interface type. and add a enum definitions for
our diet field:

```typescript
builder.interfaceType(Animal, {
  name: 'AnimalFromClass',
  fields: (t) => ({
    diet: t.expose('diet', {
      type: Diet,
    }),
  }),
});

builder.enumType(Diet, {
  name: 'Diet',
});
```

## implementing interfaces with object types

```typescript
builder.objectType(Giraffe, {
  name: 'Giraffe',
  interfaces: [Animal],
  isTypeOf: (value) => value instanceof Giraffe,
  fields: (t) => ({
    name: t.exposeString('name', {}),
  }),
});
```

There are 2 new properties here: `interfaces` and `isTypeOf`.

Interfaces is an array of interfaces that the object type implements, and `isTypeOf` is a function
that is run whenever we have an object of the interface type and we want to see if it's actually an
instance of our object type.

## Using an Interface as a return type

Using interfaces as return types for fields works just like objects:

```typescript
builder.queryFields((t) => ({
  animal: t.field({
    type: 'Animal',
    resolve: () => new Giraffe('James', new Date(Date.UTC(2012, 11, 12)), 5.2),
  }),
}));
```

## Querying interface fields

We can query interface fields like diet on any field that returns a giraffe:

```graphql
query {
  giraffe {
    name
    diet
  }
}
```

or we can query a field that returns an interface and select different fields depending on the
concrete type:

```graphql
query {
  animal {
    diet
    ... on Giraffe {
      name
    }
  }
}
```
